﻿using Domain.IRepositorys;
using Domain.Model;
using Domain.Services;
using DTO;
using Infrastructure.Error;
using Infrastructure.UniOfWorkBase;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Text;

namespace Application.App
{
    public class WxMiniApplication
    {
        public IUserRepository userRepository { get; set; }
        public IWxMiniRepository wxMiniRepository { get; set; }
        public ILoginLogRepository userLoginRepository { get; set; }
        public UserService userService { get; set; }
        public IEFUnitOfWork efUnitOfWork { get; set; }
        public IGeTuiRelationRepository geTuiRelationRepository { get; set; }
        public IMService iMService { get; set; }
        public UserLoginOutput WxMiniLogin(string invitationCode, string phone, string unionId, string openId, string headimg,string nickname, string IP, string data)
        {
            LoginLogAggregate loginLog = new LoginLogAggregate();

            loginLog.CT = loginLog.UT = DateTime.Now;
            loginLog.Platfrom = "小程序";
            loginLog.IP = IP;

            UserInfoAggregate u = null;

            if (!string.IsNullOrWhiteSpace(phone)) u = userRepository.Entities.FirstOrDefault(i => i.Phone == phone);

            if (u == null) u = userRepository.Entities.FirstOrDefault(i => i.WxUnionID == unionId);

            if (u == null)
            {
                var wx1 = wxMiniRepository.Entities.FirstOrDefault(i => i.WxOpenID == openId);
                if (wx1 != null) u = userRepository.Entities.FirstOrDefault(i => i.ID == wx1.UserID);
            }

            if (u == null)
            {
                u = userService.Register(phone, invitationCode);

                u.WxUnionID = unionId;
                u.HeadImg = headimg;
                u.NickName = nickname;                
            }
            u.LastLoginTime = DateTime.Now;

            efUnitOfWork.Commit();
            efUnitOfWork.Reset();

            loginLog.UserID = u.ID;
            userLoginRepository.Insert(loginLog);
            //设置小程序信息
            var wx = wxMiniRepository.Entities.FirstOrDefault(i => i.WxOpenID == openId);
            if (wx == null)
            {
                wx = wxMiniRepository.Entities.FirstOrDefault(i => i.UserID == u.ID);
                if (wx == null)
                {
                    wx = new WxMiniAggregate();
                    wx.UserID = u.ID;
                    wx.HeadImg = u.HeadImg;
                    wx.WxOpenID = openId;
                    wx.WxUnionID = unionId;
                    wx.WxData = data;
                    wxMiniRepository.Insert(wx);
                }
                else
                {
                    wx.UserID = u.ID;
                    wx.HeadImg = u.HeadImg;
                    wx.WxOpenID = openId;
                    wx.WxUnionID = unionId;
                    wx.WxData = data;
                    wxMiniRepository.Update(wx);
                }

                u.WxUnionID = unionId;
                u.HeadImg = headimg;
                u.NickName = nickname;
                userRepository.Update(u);
                iMService.UpdateIMUser(u);
                
            }

            efUnitOfWork.Commit();            

            return CreateToken(u);
        }
        public UserLoginOutput TryWxMiniLoginByOpenId(string openId, string IP)
        {
            LoginLogAggregate loginLog = new LoginLogAggregate();

            loginLog.CT = loginLog.UT = DateTime.Now;
            loginLog.Platfrom = "小程序";
            loginLog.IP = IP;

            UserInfoAggregate u = null;

            var wx = wxMiniRepository.Entities.FirstOrDefault(i => i.WxOpenID == openId);
            if (wx != null) u = userRepository.Entities.FirstOrDefault(i => i.ID == wx.UserID);

            if (u == null) return null;

            u.LastLoginTime = DateTime.Now;
            loginLog.UserID = u.ID;
            userLoginRepository.Insert(loginLog);

            efUnitOfWork.Commit();

            return CreateToken(u);
        }

        private UserLoginOutput CreateToken(UserInfoAggregate u)
        {
            var JwtToken = userService.CreateToken(u);

            UserLoginOutput userLoginOutput = new UserLoginOutput();

            userLoginOutput.Token = new JwtSecurityTokenHandler().WriteToken(JwtToken);
            userLoginOutput.Expiration = JwtToken.ValidTo;
            userLoginOutput.UserPhone = u.Phone;
            //userLoginOutput.NickName = u.NickName;
            userLoginOutput.TLevel = u.TraderLevel;
            userLoginOutput.ULevel = u.UserLevel;
            userLoginOutput.IMUser = "a" + u.Phone;
            userLoginOutput.IMUserPwd = iMService.GetIMUserPwd(u);
            userLoginOutput.IMUserSig = iMService.GetTXUserSig(u);
            userLoginOutput.InviteCode = u.InviteCode;

            var bind = geTuiRelationRepository.Entities.FirstOrDefault(i => i.UserID == u.ID);
            userLoginOutput.GeTuiID = bind?.GeTuiID;

            return userLoginOutput;
        }
    }
}
